#include "ManagedOdePackProvider.h"

double SmartMathLibrary::OdePack::ManagedOdePackProvider::log(double x)
{
  return System::Math::Log(x);
}

double SmartMathLibrary::OdePack::ManagedOdePackProvider::sqrt(double x)
{
  return System::Math::Sqrt(x);
}

double SmartMathLibrary::OdePack::ManagedOdePackProvider::atan(double x)
{
  return System::Math::Atan(x);
}

double SmartMathLibrary::OdePack::ManagedOdePackProvider::pow_dd(double x,
  double y)
{
  return System::Math::Pow(x, y);
}

double SmartMathLibrary::OdePack::ManagedOdePackProvider::pow_dd(doublereal *ap,
  doublereal *bp)
{
  return System::Math::Pow(*ap,  *bp);
}

double SmartMathLibrary::OdePack::ManagedOdePackProvider::d_sign(doublereal *a,
  doublereal *b)
{
  double x;
  x = (*a >= 0 ?  *a:  -  *a);
  return (*b >= 0 ? x :  - x);
}

double SmartMathLibrary::OdePack::ManagedOdePackProvider::r_sign(real *a, real
  *b)
{
  double x;
  x = (*a >= 0 ?  *a:  -  *a);
  return (*b >= 0 ? x :  - x);
}

double SmartMathLibrary::OdePack::ManagedOdePackProvider::pow_ri(real *ap,
  integer *bp)
{
  double pow, x;
  integer n;
  unsigned long u;

  pow = 1;
  x =  *ap;
  n =  *bp;

  if (n != 0)
  {
    if (n < 0)
    {
      n =  - n;
      x = 1 / x;
    }
    for (u = n;;)
    {
      if (u &01)
        pow *= x;
      if (u >>= 1)
        x *= x;
      else
        break;
    }
  }
  return (pow);
}

void SmartMathLibrary::OdePack::ManagedOdePackProvider::s_copy(register char *a,
  register char *b, ftnlen la, ftnlen lb)
{
  register char *aend,  *bend;

  aend = a + la;

  if (la <= lb)
    if (a <= b || a >= b + la)
      while (a < aend)
        *a++ =  *b++;
      else
        for (b += la; a < aend;)
          *--aend =  *--b;
        else
  {
    bend = b + lb;
    if (a <= b || a >= bend)
            while (b < bend)
              *a++ =  *b++;
            else
    {
      a += lb;
      while (b < bend)
                *--a =  *--bend;
      a += lb;
    }
    while (a < aend)
      *a++ = ' ';
  }
}

double SmartMathLibrary::OdePack::ManagedOdePackProvider::pow_di(doublereal *ap,
  integer *bp)
{
  double pow, x;
  integer n;
  unsigned long u;

  pow = 1;
  x =  *ap;
  n =  *bp;

  if (n != 0)
  {
    if (n < 0)
    {
      n =  - n;
      x = 1 / x;
    }
    for (u = n;;)
    {
      if (u &01)
        pow *= x;
      if (u >>= 1)
        x *= x;
      else
        break;
    }
  }
  return (pow);
}
